package com.czk.run.generateclass.label;

import com.czk.utils.FileUtil;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;

import static org.objectweb.asm.Opcodes.*;

/**
 * @Author:ChenZhangKun
 * @Date: 2021/7/24 15:30
 */
public class GenerateByLabel {
    public static void main(String[] args) {
        String filePath = "F:\\IdeaProjects\\asm\\target\\classes\\com\\czk\\sample\\Generate_3.class";
        System.out.println(filePath);
        // 生成字节码
        byte[] bye = generate();
        FileUtil.writeBytes(filePath, bye);
    }

    private static byte[] generate() {
        // 创建写类
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
        cw.visit(V1_8,
                ACC_PUBLIC,
                "sample/Generate_3",
                null,
                "java/lang/Object",
                null
        );
        {
            MethodVisitor mv = cw.visitMethod(ACC_STATIC + ACC_PUBLIC,
                    "test",
                    "(Z)V",
                    null,
                    null);
            Label elseLabel = new Label();
            Label returnLabel = new Label();
            // 第1段
            mv.visitCode();
            mv.visitVarInsn(ILOAD, 1);
            mv.visitJumpInsn(IFEQ, elseLabel);
            mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
            mv.visitLdcInsn("value is true");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
            mv.visitJumpInsn(GOTO, returnLabel);

// 第2段
            mv.visitLabel(elseLabel);         // 将第一个Label放到这里
            mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
            mv.visitLdcInsn("value is false");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);

// 第3段
            mv.visitLabel(returnLabel);      // 将第二个Label放到这里
            mv.visitInsn(RETURN);
            mv.visitMaxs(2, 2);
            mv.visitEnd();
        }
        cw.visitEnd();
        return cw.toByteArray();
    }
}
